package com.wmyskxz.demo.realm;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * @author Cheng JiYe
 * @description:
 * @date 2021/4/3 19:28
 */
public class MyRealm extends AuthorizingRealm {
  /** 模拟数据库数据 */
  Map<String, String> userMap = new HashMap<>(16);

  {
    userMap.put("wmyskxz", "123456");
    // 设置自定义Realm的名称，取什么无所谓..
    super.setName("myRealm");
  }

  /**
   * 授权
   *
   * @param principalCollection
   * @return
   */
  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    String userName = (String) principalCollection.getPrimaryPrincipal();
    // 从数据库获取角色和权限数据
    Set<String> roles = this.getRolesByUserName(userName);
    // 模拟从数据库中获取权限数据
    Set<String> permissions = this.getPermissionsByUserName(userName);

    SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
    simpleAuthorizationInfo.setStringPermissions(permissions);
    simpleAuthorizationInfo.setRoles(roles);
    return simpleAuthorizationInfo;
  }

  /**
   * 模拟从数据库中获取权限数据
   *
   * @param userName
   * @return
   */
  private Set<String> getPermissionsByUserName(String userName) {
    Set<String> permissions = new HashSet<>();
    permissions.add("user:delete");
    permissions.add("user:add");
    return permissions;
  }

  /**
   * 模拟从数据库中获取角色数据
   *
   * @param userName
   * @return
   */
  private Set<String> getRolesByUserName(String userName) {
    Set<String> roles = new HashSet<>();
    roles.add("admin");
    roles.add("user");
    return roles;
  }

  /**
   * 认证
   *
   * @param authenticationToken 主体传过来的认证信息
   * @return
   * @throws AuthenticationException
   */
  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
      throws AuthenticationException {
    // 1.从主体传过来的认证信息中，获得用户名
    String userName = (String) authenticationToken.getPrincipal();

    // 2.通过用户名到数据库中获取凭证
    String password = this.getPasswordByUserName(userName);
    if (password == null) {
      return null;
    }
    return new SimpleAuthenticationInfo("wmyskxz", password, "myRealm");
  }

  /**
   * 模拟从数据库取凭证的过程
   *
   * @param userName
   * @return
   */
  private String getPasswordByUserName(String userName) {
    return userMap.get(userName);
  }
}
